/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

var argscheck = require('cordova/argscheck'),
    GlobalizationError = require('org.apache.cordova.globalization.GlobalizationError');

var globalization = {
    /**
    * Returns the string identifier for the client's current language.
    * It returns the language identifier string to the successCB callback with a
    * properties object as a parameter. If there is an error getting the language,
    * then the errorCB callback is invoked.
    *
    * @param {Function} successCB
    * @param {Function} errorCB
    *
    * @return Object.value {String}: The language identifier
    *
    * @error GlobalizationError.UNKNOWN_ERROR
    *
    * Example
    *    globalization.getPreferredLanguage(function (language) {alert('language:' + language.value + '\n');},
    *                                function () {});
    */
    getPreferredLanguage:function(successCB, failureCB) {
        console.log('exec(successCB, failureCB, "Globalization","getPreferredLanguage", []);');

        tizen.systeminfo.getPropertyValue (
            "LOCALE",
            function (localeInfo) {
                console.log("Cordova, getLocaleName, language is  " + localeInfo.language);
                successCB( {"value": localeInfo.language});
            },
            function(error) {
                console.log("Cordova, getLocaleName, An error occurred " + error.message);
                failureCB(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "cannot retrieve language name"));
            }
        );
    },

    /**
    * Returns the string identifier for the client's current locale setting.
    * It returns the locale identifier string to the successCB callback with a
    * properties object as a parameter. If there is an error getting the locale,
    * then the errorCB callback is invoked.
    *
    * @param {Function} successCB
    * @param {Function} errorCB
    *
    * @return Object.value {String}: The locale identifier
    *
    * @error GlobalizationError.UNKNOWN_ERROR
    *
    * Example
    *    globalization.getLocaleName(function (locale) {alert('locale:' + locale.value + '\n');},
    *                                function () {});
    */
    getLocaleName:function(successCB, failureCB) {
        tizen.systeminfo.getPropertyValue (
            "LOCALE",
            function (localeInfo) {
                console.log("Cordova, getLocaleName, locale name (country) is  " + localeInfo.country);
                successCB( {"value":localeInfo.language});
            },
            function(error) {
                console.log("Cordova, getLocaleName, An error occurred " + error.message);
                failureCB(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "cannot retrieve locale name"));
            }
        );
    },


    /**
    * Returns a date formatted as a string according to the client's user preferences and
    * calendar using the time zone of the client. It returns the formatted date string to the
    * successCB callback with a properties object as a parameter. If there is an error
    * formatting the date, then the errorCB callback is invoked.
    *
    * The defaults are: formatLenght="short" and selector="date and time"
    *
    * @param {Date} date
    * @param {Function} successCB
    * @param {Function} errorCB
    * @param {Object} options {optional}
    *            formatLength {String}: 'short', 'medium', 'long', or 'full'
    *            selector {String}: 'date', 'time', or 'date and time'
    *
    * @return Object.value {String}: The localized date string
    *
    * @error GlobalizationError.FORMATTING_ERROR
    *
    * Example
    *    globalization.dateToString(new Date(),
    *                function (date) {alert('date:' + date.value + '\n');},
    *                function (errorCode) {alert(errorCode);},
    *                {formatLength:'short'});
    */
    dateToString:function(date, successCB, failureCB, options) {
        var dateValue = date.valueOf();
        console.log('exec(successCB, failureCB, "Globalization", "dateToString", [{"date": dateValue, "options": options}]);');

        var tzdate = null;
        var format = null;

        tzdate = new tizen.TZDate(date);

        if (tzdate) {
            if (options && (options.formatLength == 'short') ){
                format = tzdate.toLocaleDateString();
            }
            else{
                format = tzdate.toLocaleString();
            }
            console.log('Cordova, globalization, dateToString ' +format);
        }

        if (format)
        {
            successCB ({"value": format});
        }
        else {
            failureCB(new GlobalizationError(GlobalizationError.FORMATTING_ERROR , "cannot format date string"));
        }
    },


    /**
    * Parses a date formatted as a string according to the client's user
    * preferences and calendar using the time zone of the client and returns
    * the corresponding date object. It returns the date to the successCB
    * callback with a properties object as a parameter. If there is an error
    * parsing the date string, then the errorCB callback is invoked.
    *
    * The defaults are: formatLength="short" and selector="date and time"
    *
    * @param {String} dateString
    * @param {Function} successCB
    * @param {Function} errorCB
    * @param {Object} options {optional}
    *            formatLength {String}: 'short', 'medium', 'long', or 'full'
    *            selector {String}: 'date', 'time', or 'date and time'
    *
    * @return    Object.year {Number}: The four digit year
    *            Object.month {Number}: The month from (0 - 11)
    *            Object.day {Number}: The day from (1 - 31)
    *            Object.hour {Number}: The hour from (0 - 23)
    *            Object.minute {Number}: The minute from (0 - 59)
    *            Object.second {Number}: The second from (0 - 59)
    *            Object.millisecond {Number}: The milliseconds (from 0 - 999),
    *                                        not available on all platforms
    *
    * @error GlobalizationError.PARSING_ERROR
    *
    * Example
    *    globalization.stringToDate('4/11/2011',
    *                function (date) { alert('Month:' + date.month + '\n' +
    *                    'Day:' + date.day + '\n' +
    *                    'Year:' + date.year + '\n');},
    *                function (errorCode) {alert(errorCode);},
    *                {selector:'date'});
    */
    stringToDate:function(dateString, successCB, failureCB, options) {
        argscheck.checkArgs('sfFO', 'Globalization.stringToDate', arguments);
        console.log('exec(successCB, failureCB, "Globalization", "stringToDate", [{"dateString": dateString, "options": options}]);');

        //not supported
        failureCB(new GlobalizationError(GlobalizationError.PARSING_ERROR , "unsupported"));
    },


    /**
    * Returns a pattern string for formatting and parsing dates according to the client's
    * user preferences. It returns the pattern to the successCB callback with a
    * properties object as a parameter. If there is an error obtaining the pattern,
    * then the errorCB callback is invoked.
    *
    * The defaults are: formatLength="short" and selector="date and time"
    *
    * @param {Function} successCB
    * @param {Function} errorCB
    * @param {Object} options {optional}
    *            formatLength {String}: 'short', 'medium', 'long', or 'full'
    *            selector {String}: 'date', 'time', or 'date and time'
    *
    * @return    Object.pattern {String}: The date and time pattern for formatting and parsing dates.
    *                                    The patterns follow Unicode Technical Standard #35
    *                                    http://unicode.org/reports/tr35/tr35-4.html
    *            Object.timezone {String}: The abbreviated name of the time zone on the client
    *            Object.utc_offset {Number}: The current difference in seconds between the client's
    *                                        time zone and coordinated universal time.
    *            Object.dst_offset {Number}: The current daylight saving time offset in seconds
    *                                        between the client's non-daylight saving's time zone
    *                                        and the client's daylight saving's time zone.
    *
    * @error GlobalizationError.PATTERN_ERROR
    *
    * Example
    *    globalization.getDatePattern(
    *                function (date) {alert('pattern:' + date.pattern + '\n');},
    *                function () {},
    *                {formatLength:'short'});
    */
    getDatePattern:function(successCB, failureCB, options) {
        console.log(' exec(successCB, failureCB, "Globalization", "getDatePattern", [{"options": options}]);');

        var shortFormat = (options) ? ( options.formatLength === 'short') : true;

        var formatString = tizen.time.getDateFormat ( shortFormat);


        var current_datetime = tizen.time.getCurrentDateTime();

        // probably will require some control of operation...
        if (formatString)
        {
            successCB(
                {
                    "pattern": formatString,
                    "timezone": current_datetime.getTimezoneAbbreviation(),
                    "utc_offset": current_datetime.difference(current_datetime.toUTC()).length,
                    "dst_offset": current_datetime.isDST()
                }
            );
        }
        else {
            failureCB(new GlobalizationError(GlobalizationError.PATTERN_ERROR , "cannot get pattern"));
        }
    },


    /**
    * Returns an array of either the names of the months or days of the week
    * according to the client's user preferences and calendar. It returns the array of names to the
    * successCB callback with a properties object as a parameter. If there is an error obtaining the
    * names, then the errorCB callback is invoked.
    *
    * The defaults are: type="wide" and item="months"
    *
    * @param {Function} successCB
    * @param {Function} errorCB
    * @param {Object} options {optional}
    *            type {String}: 'narrow' or 'wide'
    *            item {String}: 'months', or 'days'
    *
    * @return Object.value {Array{String}}: The array of names starting from either
    *                                        the first month in the year or the
    *                                        first day of the week.
    * @error GlobalizationError.UNKNOWN_ERROR
    *
    * Example
    *    globalization.getDateNames(function (names) {
    *        for(var i = 0; i < names.value.length; i++) {
    *            alert('Month:' + names.value[i] + '\n');}},
    *        function () {});
    */
    getDateNames:function(successCB, failureCB, options) {
        argscheck.checkArgs('fFO', 'Globalization.getDateNames', arguments);
        console.log('exec(successCB, failureCB, "Globalization", "getDateNames", [{"options": options}]);');

        failureCB(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "unsupported"));
    },

    /**
    * Returns whether daylight savings time is in effect for a given date using the client's
    * time zone and calendar. It returns whether or not daylight savings time is in effect
    * to the successCB callback with a properties object as a parameter. If there is an error
    * reading the date, then the errorCB callback is invoked.
    *
    * @param {Date} date
    * @param {Function} successCB
    * @param {Function} errorCB
    *
    * @return Object.dst {Boolean}: The value "true" indicates that daylight savings time is
    *                                in effect for the given date and "false" indicate that it is not.
    *
    * @error GlobalizationError.UNKNOWN_ERROR
    *
    * Example
    *    globalization.isDayLightSavingsTime(new Date(),
    *                function (date) {alert('dst:' + date.dst + '\n');}
    *                function () {});
    */
    isDayLightSavingsTime:function(date, successCB, failureCB) {

        var tzdate = null,
            isDLS = false;

        console.log('exec(successCB, failureCB, "Globalization", "isDayLightSavingsTime", [{"date": dateValue}]);');
        console.log("date " + date + " value " + date.valueOf()) ;

        tzdate = new tizen.TZDate(date);
        if (tzdate) {
            isDLS = false | (tzdate && tzdate.isDST());

            console.log ("Cordova, globalization, isDayLightSavingsTime, " + isDLS);

            successCB({"dst":isDLS});
        }
        else {
            failureCB(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "cannot get information"));
        }
    },

    /**
    * Returns the first day of the week according to the client's user preferences and calendar.
    * The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
    * It returns the day to the successCB callback with a properties object as a parameter.
    * If there is an error obtaining the pattern, then the errorCB callback is invoked.
    *
    * @param {Function} successCB
    * @param {Function} errorCB
    *
    * @return Object.value {Number}: The number of the first day of the week.
    *
    * @error GlobalizationError.UNKNOWN_ERROR
    *
    * Example
    *    globalization.getFirstDayOfWeek(function (day)
    *                { alert('Day:' + day.value + '\n');},
    *                function () {});
    */
    getFirstDayOfWeek:function(successCB, failureCB) {
        argscheck.checkArgs('fF', 'Globalization.getFirstDayOfWeek', arguments);
        console.log('exec(successCB, failureCB, "Globalization", "getFirstDayOfWeek", []);');

        // there is no API to get the fist day of the week in Tizen Dvice API
        successCB({value:1});

        // first day of week is a settings in the date book app
        // what about : getting the settings directly or asking the date book ?
    },


    /**
    * Returns a number formatted as a string according to the client's user preferences.
    * It returns the formatted number string to the successCB callback with a properties object as a
    * parameter. If there is an error formatting the number, then the errorCB callback is invoked.
    *
    * The defaults are: type="decimal"
    *
    * @param {Number} number
    * @param {Function} successCB
    * @param {Function} errorCB
    * @param {Object} options {optional}
    *            type {String}: 'decimal', "percent", or 'currency'
    *
    * @return Object.value {String}: The formatted number string.
    *
    * @error GlobalizationError.FORMATTING_ERROR
    *
    * Example
    *    globalization.numberToString(3.25,
    *                function (number) {alert('number:' + number.value + '\n');},
    *                function () {},
    *                {type:'decimal'});
    */
    numberToString:function(number, successCB, failureCB, options) {
        argscheck.checkArgs('nfFO', 'Globalization.numberToString', arguments);
        console.log('exec(successCB, failureCB, "Globalization", "numberToString", [{"number": number, "options": options}]);');
        //not supported
        failureCB(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "unsupported"));
    },

    /**
    * Parses a number formatted as a string according to the client's user preferences and
    * returns the corresponding number. It returns the number to the successCB callback with a
    * properties object as a parameter. If there is an error parsing the number string, then
    * the errorCB callback is invoked.
    *
    * The defaults are: type="decimal"
    *
    * @param {String} numberString
    * @param {Function} successCB
    * @param {Function} errorCB
    * @param {Object} options {optional}
    *            type {String}: 'decimal', "percent", or 'currency'
    *
    * @return Object.value {Number}: The parsed number.
    *
    * @error GlobalizationError.PARSING_ERROR
    *
    * Example
    *    globalization.stringToNumber('1234.56',
    *                function (number) {alert('Number:' + number.value + '\n');},
    *                function () { alert('Error parsing number');});
    */
    stringToNumber:function(numberString, successCB, failureCB, options) {
        argscheck.checkArgs('sfFO', 'Globalization.stringToNumber', arguments);
        console.log('exec(successCB, failureCB, "Globalization", "stringToNumber", [{"numberString": numberString, "options": options}]);');

        //not supported
        failureCB(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "unsupported"));
    },

    /**
    * Returns a pattern string for formatting and parsing numbers according to the client's user
    * preferences. It returns the pattern to the successCB callback with a properties object as a
    * parameter. If there is an error obtaining the pattern, then the errorCB callback is invoked.
    *
    * The defaults are: type="decimal"
    *
    * @param {Function} successCB
    * @param {Function} errorCB
    * @param {Object} options {optional}
    *            type {String}: 'decimal', "percent", or 'currency'
    *
    * @return    Object.pattern {String}: The number pattern for formatting and parsing numbers.
    *                                    The patterns follow Unicode Technical Standard #35.
    *                                    http://unicode.org/reports/tr35/tr35-4.html
    *            Object.symbol {String}: The symbol to be used when formatting and parsing
    *                                    e.g., percent or currency symbol.
    *            Object.fraction {Number}: The number of fractional digits to use when parsing and
    *                                    formatting numbers.
    *            Object.rounding {Number}: The rounding increment to use when parsing and formatting.
    *            Object.positive {String}: The symbol to use for positive numbers when parsing and formatting.
    *            Object.negative: {String}: The symbol to use for negative numbers when parsing and formatting.
    *            Object.decimal: {String}: The decimal symbol to use for parsing and formatting.
    *            Object.grouping: {String}: The grouping symbol to use for parsing and formatting.
    *
    * @error GlobalizationError.PATTERN_ERROR
    *
    * Example
    *    globalization.getNumberPattern(
    *                function (pattern) {alert('Pattern:' + pattern.pattern + '\n');},
    *                function () {});
    */
    getNumberPattern:function(successCB, failureCB, options) {
        argscheck.checkArgs('fFO', 'Globalization.getNumberPattern', arguments);
        console.log('exec(successCB, failureCB, "Globalization", "getNumberPattern", [{"options": options}]);');

        //not supported
        failureCB(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "unsupported"));
    },

    /**
    * Returns a pattern string for formatting and parsing currency values according to the client's
    * user preferences and ISO 4217 currency code. It returns the pattern to the successCB callback with a
    * properties object as a parameter. If there is an error obtaining the pattern, then the errorCB
    * callback is invoked.
    *
    * @param {String} currencyCode
    * @param {Function} successCB
    * @param {Function} errorCB
    *
    * @return    Object.pattern {String}: The currency pattern for formatting and parsing currency values.
    *                                    The patterns follow Unicode Technical Standard #35
    *                                    http://unicode.org/reports/tr35/tr35-4.html
    *            Object.code {String}: The ISO 4217 currency code for the pattern.
    *            Object.fraction {Number}: The number of fractional digits to use when parsing and
    *                                    formatting currency.
    *            Object.rounding {Number}: The rounding increment to use when parsing and formatting.
    *            Object.decimal: {String}: The decimal symbol to use for parsing and formatting.
    *            Object.grouping: {String}: The grouping symbol to use for parsing and formatting.
    *
    * @error GlobalizationError.FORMATTING_ERROR
    *
    * Example
    *    globalization.getCurrencyPattern('EUR',
    *                function (currency) {alert('Pattern:' + currency.pattern + '\n');}
    *                function () {});
    */
    getCurrencyPattern:function(currencyCode, successCB, failureCB) {
        argscheck.checkArgs('sfF', 'Globalization.getCurrencyPattern', arguments);
        console.log('exec(successCB, failureCB, "Globalization", "getCurrencyPattern", [{"currencyCode": currencyCode}]);');

        //not supported
        failureCB(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "unsupported"));
    }
};

module.exports = globalization;

require("cordova/tizen/commandProxy").add("Globalization", module.exports);
